package com.nl.lib_core.tool

import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern

object IdCardUtil {
  /*
  校验规则：
      如果为15位，只能是15位数字；前两位满足省/直辖市的行政区划代码。
      如果为18位，允许为18位数字，如出现字母只能在最后一位，且仅能为“X”；
      18位中包含年月的字段满足日期的构成规则；前两位满足省/直辖市的行政区划代码；
      最后一位校验位满足身份证的校验规则（身份证校验规则见附录）。
      附录：身份证校验规则
          公民身份证号码校验公式为RESULT = ∑( A[i] * W[i] ) mod 11。
          其中,i表示号码字符从右至左包括校验码在内的位置序号;A[i]表示第I位置上的数字的数值;W[i]表示第i位置上的加权因子,其值如下:

          i 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2
          W[i] 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

          RESULT 0 1 2 3 4 5 6 7 8 9 10
          校验码A[1] 1 0 X 9 8 7 6 5 4 3 2
   */
  fun idCardValidate(idCard: String): Boolean {
    val valCodeArr = arrayOf("1", "0", "x", "9", "8", "7", "6", "5", "4", "3", "2")
    val wi =
        arrayOf(
            "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2")
    var ai = ""
    var ai1 = ""
    var ai2 = ""

    // 号码的长度 15位或18位
    if (idCard.length != 15 && idCard.length != 18) {
      return false
    }

    // 数字 除最后以为都为数字
    if (idCard.length == 18) {
      ai = idCard.substring(0, 17)
    } else if (idCard.length == 15) {
      ai = idCard.substring(0, 6) + "19" + idCard.substring(6, 15)
    }
    if (!isNumeric(ai)) {
      return false
    }

    // 出生年月是否有效
    val strYear = ai.substring(6, 10) // 年份
    val strMonth = ai.substring(10, 12) // 月份
    val strDay = ai.substring(12, 14) // 月份
    if (!isDataFormat("$strYear-$strMonth-$strDay")) {
      return false
    }
    val gc = GregorianCalendar()
    val s = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
    try {
      if (gc[Calendar.YEAR] - strYear.toInt() > 150 ||
          gc.time.time - s.parse("$strYear-$strMonth-$strDay").time < 0) {
        return false
      }
    } catch (e: Exception) {
      e.printStackTrace()
    }
    if (strMonth.toInt() > 12 || strMonth.toInt() == 0) {
      return false
    }
    if (strDay.toInt() > 31 || strDay.toInt() == 0) {
      return false
    }

    // 地区码是否有效
    val h = areaCode
    if (h[ai.substring(0, 2)] == null) {
      return false
    }

    // 判断最后一位的值
    var totalmulAiWi = 0
    for (i in 0..16) {
      totalmulAiWi = totalmulAiWi + ai[i].toString().toInt() * wi[i].toInt()
    }
    val modValue = totalmulAiWi % 11
    val strVerifyCode = valCodeArr[modValue]
    ai1 = ai + strVerifyCode.uppercase(Locale.getDefault())
    ai2 = ai + strVerifyCode.lowercase(Locale.getDefault())
    if (idCard.length == 18) {
      if (ai1 != idCard && ai2 != idCard) {
        return false
      }
    }
    return true
  }

  private fun isNumeric(str: String): Boolean {
    val pattern = Pattern.compile("[0-9]*")
    val isNum = pattern.matcher(str)
    return isNum.matches()
  }

  private fun isDataFormat(str: String): Boolean {
    var flag = false
    val regxStr =
        "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$"
    val pattern1 = Pattern.compile(regxStr)
    val isNo = pattern1.matcher(str)
    if (isNo.matches()) {
      flag = true
    }
    return flag
  }

  private val areaCode: Hashtable<String, String>
    get() {
      val hashtable: Hashtable<String, String> = Hashtable<String, String>()
      hashtable["11"] = "北京"
      hashtable["12"] = "天津"
      hashtable["13"] = "河北"
      hashtable["14"] = "山西"
      hashtable["15"] = "内蒙古"
      hashtable["21"] = "辽宁"
      hashtable["22"] = "吉林"
      hashtable["23"] = "黑龙江"
      hashtable["31"] = "上海"
      hashtable["32"] = "江苏"
      hashtable["33"] = "浙江"
      hashtable["34"] = "安徽"
      hashtable["35"] = "福建"
      hashtable["36"] = "江西"
      hashtable["37"] = "山东"
      hashtable["41"] = "河南"
      hashtable["42"] = "湖北"
      hashtable["43"] = "湖南"
      hashtable["44"] = "广东"
      hashtable["45"] = "广西"
      hashtable["46"] = "海南"
      hashtable["50"] = "重庆"
      hashtable["51"] = "四川"
      hashtable["52"] = "贵州"
      hashtable["53"] = "云南"
      hashtable["54"] = "西藏"
      hashtable["61"] = "陕西"
      hashtable["62"] = "甘肃"
      hashtable["63"] = "青海"
      hashtable["64"] = "宁夏"
      hashtable["65"] = "新疆"
      hashtable["71"] = "台湾"
      hashtable["81"] = "香港"
      hashtable["82"] = "澳门"
      hashtable["91"] = "国外"
      return hashtable
    }
}
